<p>一. 请说出下列最终的执行结果，并解释为什么</p>
<pre>
    var a = [];
    for (var i = 0; i < 10; i++){
        a[i] = function(){
            console.log(i);
        }
    }
    a[6]();
    -----------------------------
    10;
    因为var声明的变量没有块级作用域，当循环执行完毕之后，
    i被累加到了10，所以a[6]()执行的时候访问到的变量i在当前作用域内已经变成了10
</pre>
<p>二. 请说出下列最终的执行结果，并解释为什么</p>
<pre>
    var tmp =123;
    if(true){
        console.log(tmp);
        let tmp;
    }
    -----------------------------
    会报错;
    因为在if条件语句内部访问tmp变量时，使用let声明的tmp还没有执行到，而let声明
    的变量不会存在变量提升，所以会报错
</pre>
<p>三. 结合ES6新语法，用最简单的方式找出数组中的最小值</p>
<pre>
    var arr = [12, 34, 32, 89, 4];
    -----------------------------
    let min = Math.min(...arr);
</pre>
<p>四. 请详细说明var, let, const 三种生命变量的方式之间的具体差别</p>
<pre>
    var 声明的变量会存在变量提升，可以先使用，后命名，默认值为undefined,可以重复命名相同名称的变量，后者会覆盖前者，可以随意改变变量的值，且不受块级作用域的限制， 会受到函数作用域的限制
    let 声明的变量不会存在变量提升，不可以先使用，后命名，不能重复命名相同名称的变量，可以随意改变变量的值，有块级作用域， 会受到函数作用域的限制
    const 声明的变量不会存在变量提升，不可以先使用，后命名,不能重复命名相同名称的变量，不可以随意改变变量的值，有块级作用域， 会受到函数作用域的限制
</pre>
<p>五. 请说出下列代码最终输出的结果，并解释为什么</p>
<pre>
    var a = 10;
    var obj = {
        a: 20,
        fn(){
            setTimeout(() => {
                console.log(this.a);
            })
        }
    }
    obj.fn();
    -----------------------------
    20;
    因为箭头函数不会改变this的指向，也就是说setTimeout里面的this指向和外面的this是一样的
</pre>
<p>六. 简述Symbol类型的用途</p>
<pre>
    Symbol是es2015新增的数据类型，可以生成一个唯一的值，可以用于class内部实现私有变量
    可以用于需要唯一性的地方，可以防止数据重复，被覆盖的问题
</pre>
<p>七. 说说什么是浅拷贝，什么是深拷贝</p>
<pre>
    浅拷贝就是拷贝对象的引用
    深拷贝就是拷贝对象本身
</pre>
<p>八. 请简述TypeScript和JavaScript之间的关系</p>
<pre>
    typescript是javascript的一个超集，可以使用javascript中的所有语法，自己另外建立了一套数据系统
    可以编译为javascript，支持ecmascript的新特性
</pre>
<p>九. 请谈谈你所认为的TypeScript优缺点</p>
<pre>
    优点: 强大的类型系统，可以定义变量，对象，函数等的数据类型，在编写阶段就能发现一些常见的语法问题
    支持es的最新特性，可以编译回javascript，最低可以支持到es3版本，渐进式语法，完全支持js的语法，即使不懂也可以使用
    有完善的生态和解决方案
    缺点：新增了很多的概念，增加了学习成本，对于小项目来说，前期增加了开发成本,有些第三方库没有提供对应的声明文件
</pre>
<p>十. 描述引用计数的工作原理和优缺点</p>
<pre>
    工作原理，跟踪变量，并对其设置一个引用计数器，当该变量的引用数增加就把引用计数器的值+1，反之-1
    当该变量的引用数值为0 ，则说明该变量已没有被使用，开始进行回收
    优点：发现垃圾时立即回收   最大限度减少程序暂停
    缺点：无法回收循环引用对象， 相对于其他算法时间开销较大
</pre>
<p>十一. 描述标记整理算法的工作流程</p>
<pre>
    首先遍历所有对象，找到活动对象（通过根元素可以直接和间接访问到）打上标记
    然后将这些活动对象的位置空间进行整理，使其连续分布，减少空间的浪费
    然后将没有标记的活动对象进行回收，并且解除之前添加的标记
</pre>
<p>十二. 描述V8中新生代存储区垃圾回收的流程</p>
<pre>
    首先对from区域进标记整理后将活动对象拷贝至to空间，然后释放掉from空间，然后将form与to空间进行交换
    from就变成了to,to 就变成了from
    在满足以下条件时会触发晋升操作，就是指将新生代对象移动到老生代
    1. 一轮GC后还存活的新生代对象
    2. To空间的使用率超过了25%
</pre>
<p>十三. 描述增量标记算法在何时使用及工作原理</p>
<pre>
    增量标记在V8回收老生代对象时使用，因为执行垃圾回收的时候，会暂停javascript的运行，所以长时间的垃圾回收会造成明显的卡顿
    工作原理：将垃圾回收过程进行拆分，然后让javascript执行与拆分后的回收操作交替进行，直到完成回收
    可以最大限度的减少卡顿
</pre>

